package com.hd.trans.files.model;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;

import com.hd.trans.files.bean.Audio;
import com.hd.trans.files.interf.OnShowScanFileInterface;
import com.hd.trans.utils.StorageUtils;

import java.io.File;
import java.io.IOException;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;

public class MusicItems extends ArrayList<MusicItem> {
    private final long serialVersionUID = 1L;
    private final String TAG = "MusicItems";
    private Context mContext;
    /**
     * 提供检索框架和元数据从一个输入媒体文件的统一接口（版本大于或等于2.3.3）
     */
//    private MediaMetadataRetriever mRetriever;
    private Resources m_resSystem;
    private HashSet<String> m_hsCheckPathDuplicate = new HashSet<String>(); // 检测路径重复
    /**
     * 扫描SD目录路径 天天动听允许更改下载目录，默认都在“/ttpod”下 QQ音乐播放器也允许改变，但是必须有多张SD卡
     * 百度音乐允许更改下载目录，到处都可以，使用默认路径 多米音乐播放器允许改变下载目录，但是必须有多张SD卡
     */
    private String[] defaultDirectory = {"/ttpod/", "/qqmusic/",
            "/Baidu_music/", "/DUOMI/", "/kgmusic/"};
    /**
     * 定义扫描类型
     */
    private final int defaultScan = 1, fastScan = 2, customScan = 3;
    private boolean m_isCancel;
    private ArrayList<Audio> audioList = new ArrayList<>();
    /**
     * 最近一次扫描路径
     */
    private String lastScanPath;
    private final File ROOT_SD_DIR;

    public MusicItems() {
        ROOT_SD_DIR = new File(StorageUtils.getStorageDirectory());
    }

    public MusicItems(Context context) {
        this();
        this.mContext = context;
    }

    /**
     * 加载音乐项(两种方式读取)
     *
     * @param scanType
     * @param scanDirectory
     * @return
     */
    @SuppressLint("DefaltLocale")
    public ArrayList<Audio> loadMusicItems(int scanType, ArrayList<String> scanDirectory, String text) {
        audioList.clear();

         if (scanType == customScan) {
            for (int i = 0; i < scanDirectory.size(); i++) {
                if (m_isCancel) {
                    break;
                }
                try {
                    File file = new File(scanDirectory.get(i)).getCanonicalFile();
                    if (isFilterDirectoryOrFile(file.getAbsolutePath()) || file.getAbsolutePath().equals(lastScanPath) ||
                            (ROOT_SD_DIR.getParentFile().equals(file.getParentFile()) && !ROOT_SD_DIR.equals(file))) {
                        // || file.equals(sdRoot.getParent())
                        continue;
                    }
                    lastScanPath = file.getAbsolutePath();
                    scanFile(file, text);
                } catch (IOException e) {

                }
            }
        }
        //取消扫描
//        if (!m_isCancel) {//取消扫描
//            ArrayList<MusicItem> allMusicItems = SDMusicData.getInstance()
//                    .queryAll();
//            for (MusicItem musicItem : allMusicItems) {
//                musicItem.setTitleSortKey(HanziToPinyin.getPinyinName(musicItem.getTitle()));
//                if (isMusicAvaliable(musicItem.getPath())) {
//                    this.add(musicItem);
//                }
//            }
//        }

        if (mScanFileInterface != null) {
            mScanFileInterface.scanNewFileNum(audioList.size());
        }
        Collections.sort(this, new MusicItemsComparator());// 排序
        // 建立字母索引
        HashMap<Character, Integer> alphaIndex = new HashMap<Character, Integer>();
        for (int i = 0; i < this.size(); i++) {
            Character letter = this.get(i).getLetter();
            Character lastLetter = (i - 1) >= 0 ? (this.get(i - 1).getLetter())
                    : ' ';
            if (!lastLetter.equals(letter)) {
                alphaIndex.put(letter, i);
            }
        }
        return audioList;
    }

    /**
     * 扫描内容提供者
     */
    private void scanContentProvider() {
        // ******************系统内容提供者************************
        Cursor cursor = mContext.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,// 获取媒体仓库中音频文件路径
                new String[]{MediaStore.Audio.Media.TITLE,// 标题
                        MediaStore.Audio.Media.DURATION,// 播放时间
                        MediaStore.Audio.Media.ARTIST,// 歌手名称
                        MediaStore.Audio.Media._ID,// id编号
                        MediaStore.Audio.Media.DISPLAY_NAME,// 文件名称
                        MediaStore.Audio.Media.DATA}, null, null,// 文件路径
                MediaStore.Audio.Media.TITLE_KEY);// 排序顺序的条件
        // **********音乐播放器目录（天天动听、百度音乐、QQ播放器）**********判断版本大于或等于2.3.3
//        mRetriever = new MediaMetadataRetriever();

        MusicItem musicItem;
        // 游标不断移动读取下一条数据
        while (cursor.moveToNext() && !m_isCancel) {
            musicItem = new MusicItem();
            musicItem.setId(cursor.getInt(3));
            musicItem.setTitle(cursor.getString(0));
            musicItem.setPath(cursor.getString(5));
            String art = cursor.getString(2);
            if (!TextUtils.isEmpty(art) && art.contains("<unknown>")) {
                art = "";
            }
            musicItem.setArt(art);
            musicItem.setDuration(cursor.getLong(1));
            if (musicItem.getDuration() == 0) {
                readMusicInfo(musicItem, null, false);
            }
            musicItem.setExtFile(true);
           /* if (isMusicAvaliable(musicItem.getPath())
                    && musicItem.getDuration() >= 1000) {
                SDMusicData.getInstance().insertData(musicItem);
            }*/
        }
        cursor.close();// 数据库扫描完成关闭游标
    }

    private String name = "";
    private int id = 0;

    /**
     * 扫描音乐文件
     *
     * @param file
     */
    private List<Audio> scanFile(File file, String text) {
        if (!file.exists() || m_isCancel) {
            return null;
        }


        // 判断是否是一个标准的文件,
        if (file.isFile() && !file.isHidden()) {
            String extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
            String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            String path = null;
            try {
                path = file.getCanonicalPath().toLowerCase(Locale.getDefault());
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (mScanFileInterface != null) {
                mScanFileInterface.scanFilePath(path);
            }
            if (mime == null || !mime.contains("audio")) {//不是音频
                return null;
            }
            if (isMusicAvaliable(path) && !name.equals(file.getName())) {
                MusicItem item = new MusicItem();
                item.setTitle(file.getName());
                item.setPath(file.getAbsolutePath());
                item.setArt("");
                readMusicInfo(item, file, false);
                /*if (item.getDuration() >= 1000) {
                    SDMusicData.getInstance().insertData(item);
                }*/
                long times = item.getDuration();

                if (text.equals("录音Sounds") && times >= 1000) {
                    String url = file.getAbsolutePath();
                    id = id + 1;
                    String title = file.getName();
                    String display_name = file.getName();
                    String album = "录音文件";
                    String artist = "手机";
                    String year = new SimpleDateFormat("yyyy-MM-dd").format(new Date(file.lastModified())); //new Date(files[i].lastModified()).toString();
                    long size = file.length();
                    String time = "空空";
                    String[] timess = {"2020年"};
                    long lastModified = file.lastModified();//AudioUtils.getMusicItemDuration(url);//file.lastModified(); 创建时间
                    Audio audio = new Audio(id, title, album, artist, url, display_name, year, time, size, timess, times, false, lastModified);
                    audioList.add(audio);
                } else {
                    if (/*times >= 1000 &&*/ file.getName().toLowerCase().contains(text.toLowerCase())) {
                        Audio audio = new Audio(id, file.getName(), file.getAbsolutePath(), file.lastModified(), 0, file.length());
                        audio.setUrl(file.getAbsolutePath());
                        audio.setDisplay_name(file.getName());
                        if (times <= 0) {
                            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                            /*long duration = AudioUtils.getMusicItemDuration(audio.getUrl(), retriever);
                            audio.setDurations(duration);
                            audio.setDuration(duration);*/
                        } else {
                            audio.setDurations(times);
                            audio.setDuration(times);
                        }
                        String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date(file.lastModified())); //new Date(files[i].lastModified()).toString();
                        audio.setModifyTime(new SimpleDateFormat("yyyy MM dd").format(file.lastModified()).split(" "));
                        audio.setYear(time);
                        audio.setTimes(file.lastModified());
                        audio.setSize(file.length());
//                        audio.setImageRes(R.drawable.icon_media_list_paly);
                        audioList.add(audio);
                    }
                }
            }
        } else if (file.isDirectory()) {// 文件是否是一个目录
            // 获取路径名中的所有目录中的文件，返回一个文件数组
            File[] files = file.listFiles();
//            File fCheck = new File(file, ".nomedia");
            if (files != null) {
                // 先排除当前是否存在".nomedia"的情况，在
                for (int i = 0; i < files.length; i++) {
                    if (m_isCancel) {
                        return null;
                    }
                    if (isFilterDirectoryOrFile(files[i].getAbsolutePath()
                            .toLowerCase())
                            || (ROOT_SD_DIR.getParentFile().equals(
                            files[i].getParentFile()) && !ROOT_SD_DIR
                            .equals(files[i]))) {
                        continue;
                    }
                    try {
                        File file2 = new File(files[i].getCanonicalPath());
                        if (file2.getAbsolutePath().equals(lastScanPath)) {
                            continue;
                        }
                        lastScanPath = file2.getAbsolutePath();
                        if (file != file2) {
                            scanFile(file2, text);
                        }

                    } catch (IOException e) {
                        Log.w(TAG, "扫描路径异常：" + e.getMessage());
                    }
                }
            }
        }
        return audioList;
    }

    /**
     * 过滤文件
     *
     * @param name
     * @return
     */
    private boolean isFilterDirectoryOrFile(String name) {
        return name.indexOf(StorageUtils.getStorageDirectory() + "data/") != -1
                || name.indexOf("/sys/") != -1;
    }

    /**
     * 读取音乐信息
     *
     * @param item
     * @param fileMusic     音乐路径
     * @param bOnlyDuration 只获取音乐持续时间
     */
    private void readMusicInfo(MusicItem item, File fileMusic, boolean bOnlyDuration) {
        if (null == fileMusic) {
            fileMusic = new File(item.getPath());
        }
        if (!fileMusic.exists()) {
            return;
        }
        try {
//            if (mRetriever == null){
//                mRetriever = new MediaMetadataRetriever();
//            }
            if (/*null != mRetriever &&*/ fileMusic.exists()) {
/*                ((MediaMetadataRetriever) mRetriever).setDataSource(fileMusic
                        .getAbsolutePath());*/
                if (!bOnlyDuration) {
                    item.setTitle(/*((MediaMetadataRetriever) mRetriever)
                            .extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)*/fileMusic.getName());
                    item.setTitle(handleStringGBK(item.getTitle()));
                }
//                item.setDuration(Integer.parseInt(((MediaMetadataRetriever) mRetriever)
//                        .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)));
                return;
            }
        } catch (Exception ex) {
        }
        if (!bOnlyDuration) {
            try {
                if (fileMusic.getName().indexOf('.') >= 0) {
                    try {
                        String[] arr = fileMusic.getName().split(".");
                        if (null != arr && arr.length > 0) {
                            item.setTitle(arr[0]);
                        } else {
                            item.setTitle(fileMusic.getName());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        item.setTitle(fileMusic.getName());
                    }

                } else {
                    item.setTitle(fileMusic.getName());
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                item.setTitle(fileMusic.getName());
            }
        }
        //item.setDuration(getMusicItemDuration(fileMusic.getAbsolutePath()));
    }

    /**
     * 修正乱码
     *
     * @param value
     * @return
     */
    public String handleStringGBK(String value) {
        try {
            if (value.equals(new String(value.getBytes("ISO-8859-1"),
                    "ISO-8859-1"))) {
                return new String(value.getBytes("ISO-8859-1"), "GBK");
            }
        } catch (Exception e) {
        }
        return value;
    }

    /**
     * 音乐文件是否可用
     *
     * @param path 音乐文件路径
     * @return
     */
    private boolean isMusicAvaliable(String path) {
        if (!TextUtils.isEmpty(path)) {
            File file = new File(path);
            return file.exists();
        } else {
            return false;
        }
    }

    /**
     * 使用MediaPlay获取播放时长
     *
     * @param path 音乐文件的路径
     * @return 时长
     */
    private int getMusicItemDuration(String path) {
        int duration = 0; //读取持续时间
        try {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(path);
            duration = Integer.parseInt(
                    retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return duration;
    }


    /**
     * 添加一项音乐
     */
    @Override
    public boolean add(MusicItem item) {

        if (m_hsCheckPathDuplicate.add(item.getPath())) {
            return super.add(item);
        } else {
            return false;
        }
    }

    /**
     * 清理所有
     */
    @Override
    public void clear() {
        m_hsCheckPathDuplicate.clear();
        super.clear();
    }

    /**
     * 移除某一项
     */
    @Override
    public MusicItem remove(int index) {
        MusicItem item = super.remove(index);
        m_hsCheckPathDuplicate.remove(item.getPath());
        return item;
    }

    public static class MusicItemsComparator implements Comparator<MusicItem> {
        private Collator mCollator = Collator.getInstance();

        @Override
        public int compare(MusicItem lhs, MusicItem rhs) {
            String strLHSTitle = lhs.getTitleSortKey();
            String strRHSTitle = rhs.getTitleSortKey();
            return mCollator.compare(strLHSTitle, strRHSTitle);
        }
    }

    /**
     * 设置是否取消加载
     *
     * @param isCancel
     */
    public void setIsCancel(boolean isCancel) {
        this.m_isCancel = isCancel;
    }

    public boolean isCancel() {
        return m_isCancel;
    }

    /**
     * 显示扫描文件的路径的接口
     */
    private OnShowScanFileInterface mScanFileInterface;

    /**
     * 注册显示扫描文件发路径的接口
     *
     * @param fileInterface
     */
    public void setOnShowScanFileInterface(OnShowScanFileInterface fileInterface) {
        this.mScanFileInterface = fileInterface;
    }

}